package llmserviceopenai.routes

import llmserviceopenai.model.ChatCompletionRequest
import llmserviceopenai.service.ChatService
import llmserviceopenai.service.EmbeddingService
import io.ktor.http.CacheControl
import io.ktor.http.ContentType
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.request.*
import io.ktor.util.toMap
import org.slf4j.LoggerFactory
import llmserviceopenai.tools.toEmbeddingRequest
import llmserviceopenai.tools.toMilvusSearchRequest
import llmserviceopenai.tools.buildRagRequest
import ragserverengine.milvus.MilvusService


fun Route.chatRoutes(chatService: ChatService) {
    post("/v1/chat/completions") {

//        val json = Json {
//            ignoreUnknownKeys = true
//            explicitNulls = false
//        }

        val logger = LoggerFactory.getLogger(ChatService::class.java)
        val startTime = System.currentTimeMillis()

        logger.info("收到请求，方法: ${call.request.httpMethod}, 路径: ${call.request.path()}")
        logger.info("请求头: ${call.request.headers.toMap()}")

        val request = call.receive<ChatCompletionRequest>()
        val isStreaming = request.stream == true

        // 对query进行embedding
        val embeddingRequest = request.toEmbeddingRequest("Qwen3-Embedding-4B")
        // 调用embedding处理方法，然后转换成milvus接口格式
        val embeddingServiceResponsed = EmbeddingService().embeddingHandler(embeddingRequest).toMilvusSearchRequest(
            "dfmea_knowledge"
        )

        // 拿milvus客户端
        val application = call.application
        val milvusService = MilvusService(application)
        val milvusResponsed = milvusService.search(embeddingServiceResponsed)

        // 将milvus结果放到原始request中去
        val newRequest = buildRagRequest(request, milvusResponsed)

        logger.info("Received chat request: model={}, stream={}", request.model, isStreaming)
        logger.info("Request messages: {}", request.messages.map { it.content })

        if (isStreaming) {
            // 流式处理：把后端 vllm 的流式响应转为 SSE（Server-Sent Events）推给客户端
            // 注意：不对 request 做改动，假设外部传入 request.stream == true
            // 使用 Ktor 的 respondTextWriter 来持续写入事件（SSE 格式）
            call.response.cacheControl(CacheControl.NoCache(null))
            call.respondTextWriter(contentType = ContentType.Text.EventStream) {

                // 从 chatService 获取一个 Flow<String>（每个元素为后端一条事件的 payload）
                val eventFlow = chatService.streamChatCompletion(request)

                // collect 会在收到每个事件时执行，写入 SSE 格式并 flush
                eventFlow.collect { payload ->
                    // 后端可能发送特殊标识 "[DONE]" 表示流结束
                    if (payload == "[DONE]") {
                        write("data: [DONE]\n\n")
                        flush()
                        // 不主动 close writer，这里只是把结束事件发出，flow 结束后 writer 会退出
                    } else {
                        // SSE 要求每行以 data: 开头。如果 payload 有多行，逐行写并前缀 data:
                        payload.lineSequence().forEach { line ->
                            write("data: $line\n")
                            flush()
                        }
                        write("\n") // 事件结束的空行
                        flush()
                    }
                }
            }
        } else {
            val response = chatService.handleChatCompletion(request)
            call.respond(response)
            println(response)

            val duration = System.currentTimeMillis()
            val finalResponse = response.choices.firstOrNull()?.message?.content.orEmpty().trim()
            logger.info(
                "Non-streaming request completed | duration={}ms | response length={} chars",
                duration,
                finalResponse.length
            )
            logger.debug("Full assistant response: \"{}\"", finalResponse)
        }
    }

    // 添加健康检查端点
    get("/health") {
        call.respond(mapOf("status" to "ok", "service" to "llm-service-openai"))
    }
}
